package com.apobates.forum.member.impl.event;

import com.apobates.forum.member.entity.MemberGroupEnum;
import com.apobates.forum.member.entity.MemberRoleEnum;
import com.apobates.forum.member.entity.MemberStatusEnum;
import com.apobates.forum.utils.lang.EnumArchitecture;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

/**
 * 会员变化事件
 *
 * @author xiaofanku
 * @since 20200927
 */
public class MemberChangeEvent {
    private final long memberId;
    private final String key;
    private final int value;
    private final static Map<String,String> MAP_STRUCT = Map.ofEntries(Map.entry("MemberStatusEnum", "status"), Map.entry("MemberGroupEnum", "group"), Map.entry("MemberRoleEnum", "role"));

    public MemberChangeEvent(long memberId, MemberStatusEnum status) {
        this(memberId, status, MemberStatusEnum.class);
    }

    public MemberChangeEvent(long memberId, MemberRoleEnum role) {
        this(memberId, role, MemberRoleEnum.class);
    }

    public MemberChangeEvent(long memberId, MemberGroupEnum group) {
        this(memberId, group, MemberGroupEnum.class);
    }

    private MemberChangeEvent(long memberId, EnumArchitecture archite, Class<?> cls){
        if(!EnumArchitecture.class.isAssignableFrom(cls)){
            throw new IllegalStateException("参数不是合法值");
        }
        Optional<String> k = getMapKey(cls);
        if(!k.isPresent()){
            throw new IllegalStateException("不支持的Key");
        }
        this.memberId = memberId;
        this.key = k.get();
        this.value = archite.getSymbol();
    }

    public long getMemberId() {
        return memberId;
    }

    public String getKey() {
        return key;
    }

    public int getValue() {
        return value;
    }

    /**
     * 变化事件允许的映射Key
     *
     * @return
     */
    public static Set<String> allowKey(){
        return Set.copyOf(MAP_STRUCT.values());
    }

    /**
     * 根据类查询映射Key
     *
     * @param <T> EnumArchitecture的实现枚举类型
     * @param cls EnumArchitecture的实现枚举.class
     * @return
     */
    public static <T> Optional<String> getMapKey(Class<T> cls){
        String cCN = cls.getSimpleName();
        if(MAP_STRUCT.containsKey(cCN)){
            return Optional.ofNullable(MAP_STRUCT.get(cCN));
        }
        return Optional.empty();
    }

    /**
     *
     * @param <T> EnumArchitecture的实现枚举类型
     * @param cls EnumArchitecture的实现枚举.class
     * @param mapping 映射的值集合
     * @return
     */
    public static <T> Optional<T> get(Class<T> cls, Map<String,Integer> mapping){
        Optional<String> mapKey = getMapKey(cls);
        if(mapKey.isPresent() && mapping.containsKey(mapKey.get())){
            return EnumArchitecture.getInstance(mapping.get(mapKey.get()), cls);
        }
        return Optional.empty();
    }

    @Override
    public String toString() {
        return "MemberChangeEvent{" + "memberId=" + memberId + ", key=" + key + ", value=" + value + '}';
    }
}
